package com.bluexmicro.ota2.ui.screen.config.bxlink;

import androidx.annotation.NonNull;


import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.UUID;

public class BxLinkMessage {

    private final byte[] origin;
    private final byte[] payload;
    private final short code;
    private final byte version;
    private boolean correct = false;
    @NonNull
    public UUID serviceUuid;
    @NonNull
    public UUID characteristicUuid;

    public BxLinkMessage(@NonNull byte[] origin) {
        this.origin = origin;
        version = origin[3];

        code = (short) CommonUtils.toUInt16(origin[5], origin[4]);

        int len = CommonUtils.toUInt16(origin[7], origin[6]);

        payload = new byte[len];
        System.arraycopy(origin, 8, payload, 0, len);

        short crc16 = (short) CommonUtils.toUInt16(origin[origin.length - 1], origin[origin.length - 2]);

        byte[] headerAndContent = new byte[origin.length - 2];
        System.arraycopy(origin, 8, headerAndContent, 0, headerAndContent.length);
        short currentCrc16 = (short) CRC16Util.calcCrc16(headerAndContent);
        correct = currentCrc16 == crc16;
    }

    /**
     * 用于接收远端设备发过来的消息
     */
    public BxLinkMessage(@NonNull ByteBuffer buffer) {
        this.origin = buffer.array();
        buffer.position(3);
        version = buffer.get();

        buffer.position(4);
        code = buffer.getShort(4);

        buffer.position(6);
        int len = buffer.getShort() & 0xFFFF;

        buffer.position(8);
        payload = new byte[len];
        buffer.get(payload, 0, len);

        buffer.position(buffer.capacity() - 2);
        short crc16 = buffer.getShort();
        //校验crc
        buffer.position(0);
        byte[] headerAndContent = new byte[buffer.capacity() - 2];
        buffer.get(headerAndContent, 0, headerAndContent.length);
//        Log.d("BxLinkMessage: ", "headerAndContent：" + byte2hex(headerAndContent));
        short currentCrc16 = (short) CRC16Util.calcCrc16(headerAndContent);
//        Log.d("BxLinkMessage", byte2hex(buffer.array()));
//        Log.d("crc校验", currentCrc16 + "< - >" + crc16);
        correct = currentCrc16 == crc16;
    }

    public BxLinkMessage(short code, byte[] payload, byte version) {
        this.version = version;
        this.payload = payload;
        this.code = code;
        ByteBuffer buffer = ByteBuffer.allocate(8 + payload.length).order(ByteOrder.LITTLE_ENDIAN);
        buffer.put(BxLinkProtocol.bxl)
                .put((byte) 0)
                .putShort(code)
                .putShort((short) payload.length);
        if (payload.length > 0) {
            buffer.put(payload);
        }
        byte[] headerAndContent = buffer.array();
        short crc16 = (short) CRC16Util.calcCrc16(headerAndContent);
        ByteBuffer bb = ByteBuffer.allocate(headerAndContent.length + 2).order(ByteOrder.LITTLE_ENDIAN);
        bb.put(headerAndContent).putShort(crc16);
        this.origin = bb.array();
        this.correct = true;
    }

    public void setUuid(UUID serviceUuid, UUID characteristicUuid) {
        this.serviceUuid = serviceUuid;
        this.characteristicUuid = characteristicUuid;
    }

    public byte[] getOrigin() {
        return origin;
    }

    public byte[] getPayload() {
        return payload;
    }

    public short getCode() {
        return code;
    }

    public boolean isCorrect() {
        return correct;
    }

    @NonNull
    @Override
    public String toString() {

        if (code == (short) 0xffff) {
            String rsp = "0xFFFF";
            String request = String.format("0x%04X", CommonUtils.toUInt16(payload[1], payload[0]));
            byte[] params = new byte[payload.length - 2];
            System.arraycopy(payload, 2, params, 0, params.length);
            return "BxLinkMessage{ " +
                    "response_code = " + rsp +
                    ", payload = " + CommonUtils.byte2hex(payload) +
                    ", payload_request_code = " + request +
                    ", payload_params = " + CommonUtils.byte2hex(params) +
                    ", version = " + version +
                    ", correct = " + correct +
                    '}';
        } else {
            String request = String.format("0x%04X", code);
            return "BxLinkMessage{ " +
                    "payload = " + CommonUtils.byte2hex(payload) +
                    ", code = " + request +
                    ", version = " + version +
                    ", correct = " + correct +
                    '}';
        }
    }


}